package com.transaction.manage.service.dayEnd;

import com.transaction.common.base.ResultVo;
import com.transaction.common.util.ConstUtil;
import com.transaction.common.util.FileUtil;
import com.transaction.common.util.JsonUtil;
import com.transaction.common.util.ParamsUtil;
import com.transaction.manage.localMapper.*;
import com.transaction.manage.model.dto.ChannelInfo;
import com.transaction.manage.model.dto.TransContract;
import com.transaction.manage.model.vo.HandleVo;
import com.transaction.manage.service.BusinessHandleService;
import com.transaction.manage.service.TaService;
import com.transaction.manage.util.SpringUtil;
import org.apache.commons.collections.MapUtils;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.io.File;
import java.math.BigDecimal;
import java.util.*;

@Service
public class DataHandle {

    private static Logger LOGGER = LoggerFactory.getLogger(DataHandle.class);

    /**
     * 1、下载文件
     * @param channelInfo 渠道信息
     * @param handleDate    处理日期
     * @param logCode 日志编码
     * @param stepCode 步骤编码
     * @return
     */
    @Transactional(propagation = Propagation.REQUIRED,rollbackFor = Exception.class)
    public HandleVo downloadFile(ChannelInfo channelInfo, String handleDate, String logCode, Integer stepCode){

        if(channelInfo == null || StringUtils.isEmpty(handleDate) || StringUtils.isEmpty(logCode) || stepCode == null){
            return HandleVo.error("渠道信息/处理日期/日志编码//处理步骤编码为空。");
        }

        String channelCode = channelInfo.getChannelCode();

        if(StringUtils.isEmpty(channelCode)){
            return HandleVo.error("渠道编码为空。");
        }

        BusinessHandleService businessHandleService = SpringUtil.getBean(BusinessHandleService.class);

        try{
            LOGGER.info("第【{}】步开始处理。。。",stepCode);

            /**
             * TODO 从一个地方把移到系统固定的地方
             * 1、判断渠道配置的处理文件类型
             * 2、得到需要下载的所有文件名称
             * 3、判断读的文件夹下的文件是否都有
             * 4、下载文件到系统指定地方
             */

            String dealFiles = channelInfo.getDealFileType();
            if(StringUtils.isEmpty(dealFiles)){
                return HandleVo.error("需要处理的文件配置为空。");
            }

            //得到文件名称
            Set<String> fileNames = getAllNeedDownLoadFileNames(channelInfo,handleDate.replace("-",""));

            //读取文件的路径，校验是否都存在
            String readPath = FileUtil.buildSendFilePath(channelCode,handleDate.replace("-",""), ConstUtil.TRANSACTION_SIMULATE);
            String[] files = new File(readPath).list();

            if(files.length == 0){
                businessHandleService.asyncInsertLogDetail(logCode, readPath + "路径下没有文件。");
                return HandleVo.error("没有找到文件,请检查。");
            }

            List<String> errorMsg = new ArrayList<>();
            boolean flag = false;
            for (String v : fileNames) {
                if(!Arrays.asList(files).contains(v)){
                    flag = true;
                    errorMsg.add("【" + v + "】文件在文件夹【" + readPath + "】下不存在。");
                }
            }
            if(flag){
                //异步插入流程日志详情表
                businessHandleService.asyncInsertLogDetail(logCode, JsonUtil.getListStrToLineFeedJson(errorMsg));
                return HandleVo.error("下载文件缺失,请检查。");
            }

            //写入文件路径
            String writePath = FileUtil.buildReceiveFilePath(channelCode,handleDate.replace("-",""), ConstUtil.TRANSACTION_MANAGE);
            //开始下载文件
            fileNames.forEach(v->{
                FileUtil.readFileWriteFile(readPath + File.separator + v,writePath + File.separator + v);
            });

            LOGGER.info("第【{}】步处理结束。。。",stepCode);
            return HandleVo.ok();
        }catch(Exception e){
            String errorMsg = ParamsUtil.getErrorMsg(e);
            //异步插入流程日志详情表
            businessHandleService.asyncInsertLogDetail(logCode,errorMsg);
            LOGGER.error("渠道:【{}】,处理日期:【{}】,=>{DataHandle.downloadFile}<= 发生异常 => 【{}】 ,请处理。",channelCode,handleDate,errorMsg);
            LOGGER.info("第【{}】步处理结束。。。",stepCode);
            return HandleVo.error("未知异常,请【点击】查看详情。");
        }
    }

    /**
     * 2、解析下载到本地服务器的文件
     * @param channelInfo 渠道信息
     * @param handleDate 处理日期
     * @param logCode 日志编码
     * @param stepCode 处理步骤
     * @return
     */
    @Transactional(propagation = Propagation.REQUIRED,rollbackFor = Exception.class)
    public HandleVo analysisFile(ChannelInfo channelInfo, String handleDate, String logCode, Integer stepCode) {

        if (channelInfo == null || StringUtils.isEmpty(handleDate) || StringUtils.isEmpty(logCode) || stepCode == null) {
            return HandleVo.error("渠道信息/处理日期/日志编码//处理步骤编码为空。");
        }

        String channelCode = channelInfo.getChannelCode();

        if (StringUtils.isEmpty(channelCode)) {
            return HandleVo.error("渠道编码为空。");
        }

        BusinessHandleService businessHandleService = SpringUtil.getBean(BusinessHandleService.class);

        try {
            LOGGER.info("第【{}】步开始处理。。。", stepCode);
            /**
             * 1、获得需要解析的所有文件名称
             * 2、获得需要解析的文件的路径
             * 3、区分索引文件和正式文件解析
             * 4、把解析的数据插入数据表
             */
            String creatorCode = channelInfo.getSendCode();
            String receiverCode = channelInfo.getReceiveCode();
            String versionCode = channelInfo.getVersionCode();

            //得到文件名称
            Set<String> fileNames = getAllNeedDownLoadFileNames(channelInfo,handleDate.replace("-",""));
            String analysisPath = FileUtil.buildReceiveFilePath(channelCode,handleDate.replace("-",""), ConstUtil.TRANSACTION_MANAGE);

            List<String> errorMsg = new ArrayList<>();
            boolean flag = false;

            //查询对应的接口字段
            InterfaceFieldMapper interfaceFieldMapper = SpringUtil.getBean(InterfaceFieldMapper.class);
            //区分不同文件，解析方法不同
            for (String v : fileNames) {
                if(v.contains(ConstUtil.FILE_PREFIX)){
                    String fileType = v.substring(v.lastIndexOf("_") + 1,v.lastIndexOf("."));

                    List<Map<String,Object>> interfaceList = interfaceFieldMapper.selectInterfaceForMap(ConstUtil.fileAnalysisInterface.get(fileType + versionCode));
                    if(CollectionUtils.isEmpty(interfaceList)){
                        errorMsg.add("【" + v + "】文件,文件类型【"+fileType+"】没有对应的接口字段,请检查。");
                        flag = true;
                        continue;
                    }

                    //正式文件
                    File file = new File(analysisPath + File.separator + v);
                    Map<String,Object> map = FileUtil.analysisFile(creatorCode,receiverCode,versionCode,handleDate.replace("-",""),file,interfaceList,errorMsg);
                    if(MapUtils.getBoolean(map,"flag")){
                        flag = true;
                    }else{
                        //数据不为空，插入
                        List<Map<String,Object>> dataList = (List<Map<String, Object>>) MapUtils.getObject(map,"data");
                        //删除数据
                        if(CollectionUtils.isNotEmpty(dataList)){
                            //插入数据
                            businessHandleService.insertAnalysisData(channelCode,handleDate,fileType,stepCode,dataList);
                        }
                    }
                }else{
                    //索引文件
                    File file = new File(analysisPath + File.separator + v);
                    Set<String> fileNameSet = getAllNeedFileNames(channelInfo,handleDate.replace("-",""));
                    boolean retFlag = FileUtil.analysisIndexFile(creatorCode,receiverCode,versionCode,handleDate.replace("-",""),file,fileNameSet,errorMsg);
                    if(retFlag){
                        flag = true;
                    }
                }
            }

            if(flag){
                //异步插入流程日志详情表
                businessHandleService.asyncInsertLogDetail(logCode, JsonUtil.getListStrToLineFeedJson(errorMsg));
                return HandleVo.error("解析文件有误,请检查。");
            }

            LOGGER.info("第【{}】步处理结束。。。", stepCode);
            return HandleVo.ok();
        } catch (Exception e) {
            String errorMsg = ParamsUtil.getErrorMsg(e);
            //异步插入流程日志详情表
            businessHandleService.asyncInsertLogDetail(logCode, errorMsg);
            LOGGER.error("渠道:【{}】,处理日期:【{}】,=>{DataHandle.analysisFile}<= 发生异常 => 【{}】 ,请处理。", channelCode, handleDate, errorMsg);
            LOGGER.info("第【{}】步处理结束。。。", stepCode);
            return HandleVo.error("未知异常,请【点击】查看详情。");
        }
    }

    /**
     * 3、个人反洗钱数据基础校验
     * @param channelInfo 渠道信息
     * @param handleDate 处理日期
     * @param logCode 日志编码
     * @param stepCode 处理步骤
     * @return
     */
    @Transactional(propagation = Propagation.REQUIRED,rollbackFor = Exception.class)
    public HandleVo indiFxqBaseCheck(ChannelInfo channelInfo, String handleDate, String logCode, Integer stepCode){

        if (channelInfo == null || StringUtils.isEmpty(handleDate) || StringUtils.isEmpty(logCode) || stepCode == null) {
            return HandleVo.error("渠道信息/处理日期/日志编码//处理步骤编码为空。");
        }

        String channelCode = channelInfo.getChannelCode();

        if (StringUtils.isEmpty(channelCode)) {
            return HandleVo.error("渠道编码为空。");
        }

        BusinessHandleService businessHandleService = SpringUtil.getBean(BusinessHandleService.class);

        try {
            LOGGER.info("第【{}】步开始处理。。。", stepCode);

            LOGGER.info("第【{}】步处理结束。。。", stepCode);
            return HandleVo.ok();
        } catch (Exception e) {
            String errorMsg = ParamsUtil.getErrorMsg(e);
            //异步插入流程日志详情表
            businessHandleService.asyncInsertLogDetail(logCode, errorMsg);
            LOGGER.error("渠道:【{}】,处理日期:【{}】,=>{DataHandle.indiFxqBaseCheck}<= 发生异常 => 【{}】 ,请处理。", channelCode, handleDate, errorMsg);
            LOGGER.info("第【{}】步处理结束。。。", stepCode);
            return HandleVo.error("未知异常,请【点击】查看详情。");
        }
    }

    /**
     * 4、机构反洗钱数据基础校验
     * @param channelInfo 渠道信息
     * @param handleDate 处理日期
     * @param logCode 日志编码
     * @param stepCode 处理步骤
     * @return
     */
    @Transactional(propagation = Propagation.REQUIRED,rollbackFor = Exception.class)
    public HandleVo instFxqBaseCheck(ChannelInfo channelInfo, String handleDate, String logCode, Integer stepCode){
        if (channelInfo == null || StringUtils.isEmpty(handleDate) || StringUtils.isEmpty(logCode) || stepCode == null) {
            return HandleVo.error("渠道信息/处理日期/日志编码//处理步骤编码为空。");
        }

        String channelCode = channelInfo.getChannelCode();

        if (StringUtils.isEmpty(channelCode)) {
            return HandleVo.error("渠道编码为空。");
        }

        BusinessHandleService businessHandleService = SpringUtil.getBean(BusinessHandleService.class);

        try {
            LOGGER.info("第【{}】步开始处理。。。", stepCode);

            LOGGER.info("第【{}】步处理结束。。。", stepCode);
            return HandleVo.ok();
        } catch (Exception e) {
            String errorMsg = ParamsUtil.getErrorMsg(e);
            //异步插入流程日志详情表
            businessHandleService.asyncInsertLogDetail(logCode, errorMsg);
            LOGGER.error("渠道:【{}】,处理日期:【{}】,=>{DataHandle.instFxqBaseCheck}<= 发生异常 => 【{}】 ,请处理。", channelCode, handleDate, errorMsg);
            LOGGER.info("第【{}】步处理结束。。。", stepCode);
            return HandleVo.error("未知异常,请【点击】查看详情。");
        }
    }

    /**
     * 5、电子合同数据数据基础校验
     * @param channelInfo 渠道信息
     * @param handleDate 处理日期
     * @param logCode 日志编码
     * @param stepCode 处理步骤
     * @return
     */
    @Transactional(propagation = Propagation.REQUIRED,rollbackFor = Exception.class)
    public HandleVo elContractBaseCheck(ChannelInfo channelInfo, String handleDate, String logCode, Integer stepCode){
        if (channelInfo == null || StringUtils.isEmpty(handleDate) || StringUtils.isEmpty(logCode) || stepCode == null) {
            return HandleVo.error("渠道信息/处理日期/日志编码//处理步骤编码为空。");
        }

        String channelCode = channelInfo.getChannelCode();
        String versionCode = channelInfo.getVersionCode();

        if (StringUtils.isEmpty(channelCode)) {
            return HandleVo.error("渠道编码为空。");
        }

        BusinessHandleService businessHandleService = SpringUtil.getBean(BusinessHandleService.class);
        HandleDataCheck handleDataCheck = SpringUtil.getBean(HandleDataCheck.class);

        try {
            LOGGER.info("第【{}】步开始处理。。。", stepCode);

            //初始化恢复状态和错误信息
            businessHandleService.initCheckStatusAndErrorMsg("el_contract_43",channelCode,handleDate);

            //记录是否有校验错误的数据
            boolean flag = false;

            ElContract43Mapper elContract43Mapper = SpringUtil.getBean(ElContract43Mapper.class);
            List<LinkedHashMap<String,Object>> elContract43List = elContract43Mapper.selectElContract43ForMap(channelCode,handleDate);

            if(CollectionUtils.isNotEmpty(elContract43List)) {
                List<LinkedHashMap<String, Object>> checkList = new ArrayList<>();

                InterfaceFieldMapper interfaceFieldMapper = SpringUtil.getBean(InterfaceFieldMapper.class);
                List<Map<String,Object>> interfaceList = interfaceFieldMapper.selectInterfaceForMap(ConstUtil.FILE_TYPE_43 + "000" + versionCode);

                //基础校验
                boolean checkFlag = handleDataCheck.baseDataCheck(elContract43List,interfaceList,checkList,
                        null, channelCode, handleDate,ConstUtil.FILE_TYPE_43, null, stepCode);

                if(checkFlag){
                    flag = true;
                }

                //更新错误信息
                businessHandleService.updateSerialNoAndCheckErrorList("el_contract_43",elContract43List);

                //插入错误信息
                if(CollectionUtils.isNotEmpty(checkList)){
                    exchangeAndInsertErrorDetail(logCode,checkList);
                }
            }

            LOGGER.info("第【{}】步处理结束。。。", stepCode);

            if(flag){
                return HandleVo.error("电子合同校验错误,请检查。");
            }
            return HandleVo.ok();
        } catch (Exception e) {
            String errorMsg = ParamsUtil.getErrorMsg(e);
            //异步插入流程日志详情表
            businessHandleService.asyncInsertLogDetail(logCode, errorMsg);
            LOGGER.error("渠道:【{}】,处理日期:【{}】,=>{DataHandle.elContractBaseCheck}<= 发生异常 => 【{}】 ,请处理。", channelCode, handleDate, errorMsg);
            LOGGER.info("第【{}】步处理结束。。。", stepCode);
            return HandleVo.error("未知异常,请【点击】查看详情。");
        }
    }


    /**
     * 6、R1非居民数据数据基础校验
     * @param channelInfo 渠道信息
     * @param handleDate 处理日期
     * @param logCode 日志编码
     * @param stepCode 处理步骤
     * @return
     */
    @Transactional(propagation = Propagation.REQUIRED,rollbackFor = Exception.class)
    public HandleVo nonResidentBaseCheck(ChannelInfo channelInfo, String handleDate, String logCode, Integer stepCode){
        if (channelInfo == null || StringUtils.isEmpty(handleDate) || StringUtils.isEmpty(logCode) || stepCode == null) {
            return HandleVo.error("渠道信息/处理日期/日志编码//处理步骤编码为空。");
        }

        String channelCode = channelInfo.getChannelCode();
        String versionCode = channelInfo.getVersionCode();

        if (StringUtils.isEmpty(channelCode)) {
            return HandleVo.error("渠道编码为空。");
        }

        BusinessHandleService businessHandleService = SpringUtil.getBean(BusinessHandleService.class);
        HandleDataCheck handleDataCheck = SpringUtil.getBean(HandleDataCheck.class);

        try {
            LOGGER.info("第【{}】步开始处理。。。", stepCode);

            //初始化恢复状态和错误信息
            businessHandleService.initCheckStatusAndErrorMsg("non_resident_apply",channelCode,handleDate);

            //记录是否有校验错误的数据
            boolean flag = false;

            NonResidentApplyMapper nonResidentApplyMapper = SpringUtil.getBean(NonResidentApplyMapper.class);
            List<LinkedHashMap<String,Object>> nonResidentList = nonResidentApplyMapper.selectNonResidentForMap(channelCode,handleDate);

            if(CollectionUtils.isNotEmpty(nonResidentList)) {
                List<LinkedHashMap<String, Object>> checkList = new ArrayList<>();

                InterfaceFieldMapper interfaceFieldMapper = SpringUtil.getBean(InterfaceFieldMapper.class);
                List<Map<String,Object>> interfaceList = interfaceFieldMapper.selectInterfaceForMap(ConstUtil.FILE_TYPE_R1 + "000" + versionCode);

                //基础校验
                boolean checkFlag = handleDataCheck.baseDataCheck(nonResidentList,interfaceList,checkList,
                        null, channelCode, handleDate,ConstUtil.FILE_TYPE_R1, null, stepCode);

                if(checkFlag){
                    flag = true;
                }

                //更新错误信息
                businessHandleService.updateSerialNoAndCheckErrorList("non_resident_apply",nonResidentList);

                //插入错误信息
                if(CollectionUtils.isNotEmpty(checkList)){
                    exchangeAndInsertErrorDetail(logCode,checkList);
                }
            }

            LOGGER.info("第【{}】步处理结束。。。", stepCode);

            if(flag){
                return HandleVo.error("非居民校验错误,请检查。");
            }
            return HandleVo.ok();
        } catch (Exception e) {
            String errorMsg = ParamsUtil.getErrorMsg(e);
            //异步插入流程日志详情表
            businessHandleService.asyncInsertLogDetail(logCode, errorMsg);
            LOGGER.error("渠道:【{}】,处理日期:【{}】,=>{DataHandle.nonResidentBaseCheck}<= 发生异常 => 【{}】 ,请处理。", channelCode, handleDate, errorMsg);
            LOGGER.info("第【{}】步处理结束。。。", stepCode);
            return HandleVo.error("未知异常,请【点击】查看详情。");
        }
    }


    /**
     * 7、账户申请数据数据基础校验
     * @param channelInfo 渠道信息
     * @param handleDate 处理日期
     * @param logCode 日志编码
     * @param stepCode 处理步骤
     * @return
     */
    public HandleVo accountApplyBaseCheck(ChannelInfo channelInfo, String handleDate, String logCode, Integer stepCode){
        if (channelInfo == null || StringUtils.isEmpty(handleDate) || StringUtils.isEmpty(logCode) || stepCode == null) {
            return HandleVo.error("渠道信息/处理日期/日志编码//处理步骤编码为空。");
        }

        String channelCode = channelInfo.getChannelCode();
        String versionCode = channelInfo.getVersionCode();

        if (StringUtils.isEmpty(channelCode)) {
            return HandleVo.error("渠道编码为空。");
        }

        BusinessHandleService businessHandleService = SpringUtil.getBean(BusinessHandleService.class);
        HandleDataCheck handleDataCheck = SpringUtil.getBean(HandleDataCheck.class);

        try {
            LOGGER.info("第【{}】步开始处理。。。", stepCode);
            /**
             * 1、校验appSheetSerialNo是否重复
             * 2、查询校验成功的数据
             * 3、查询接口字段
             * 4、校验
             *  4.1、校验业务编码是否支持
             */
            //初始化恢复状态和错误信息
            businessHandleService.initCheckStatusAndErrorMsg("account_apply",channelCode,handleDate);

            List<String> sameAppSheetSerialNo = handleDataCheck.checkSameAppSheetSerialNo("account_apply",channelCode,handleDate);
            if(CollectionUtils.isNotEmpty(sameAppSheetSerialNo)){
                LOGGER.error("渠道:{},日期:{},账户申请有AppSheetSerialNo重复,重复号码为:{}",channelCode,handleDate,sameAppSheetSerialNo.toString());
                //更新这些数据为失败
                businessHandleService.updateStatusAndMsgByAppSheetSerialNo("account_apply",channelCode,handleDate,sameAppSheetSerialNo,"申请单编号重复请检查。");
            }


            //记录是否有校验错误的数据
            boolean flag = false;

            AccountApplyMapper accountApplyMapper = SpringUtil.getBean(AccountApplyMapper.class);
            List<LinkedHashMap<String,Object>> accountList = accountApplyMapper.selectAccountApplyForMap(channelCode,handleDate);
            if(CollectionUtils.isNotEmpty(accountList)){
                List<LinkedHashMap<String,Object>> checkList = new ArrayList<>();

                //基础校验
                boolean checkFlag = handleDataCheck.baseDataCheck(accountList,null,checkList,
                        ConstUtil.ACCOUNT_SUPPORT_BUSINESS,channelCode,handleDate,
                        ConstUtil.FILE_TYPE_01,versionCode,stepCode);

                if(checkFlag){
                    flag = true;
                }

                //更新taSerialNo和错误信息
                businessHandleService.updateSerialNoAndCheckErrorList("account_apply",accountList);

                //插入错误信息
                if(CollectionUtils.isNotEmpty(checkList)){
                    exchangeAndInsertErrorDetail(logCode,checkList);
                }
            }

            LOGGER.info("第【{}】步处理结束。。。", stepCode);

            if(flag){
                return HandleVo.error("账户校验错误,请检查。");
            }
            return HandleVo.ok();

        } catch (Exception e) {
            String errorMsg = ParamsUtil.getErrorMsg(e);
            //异步插入流程日志详情表
            businessHandleService.asyncInsertLogDetail(logCode, errorMsg);
            LOGGER.error("渠道:【{}】,处理日期:【{}】,=>{DataHandle.accountApplyBaseCheck}<= 发生异常 => 【{}】 ,请处理。", channelCode, handleDate, errorMsg);
            LOGGER.info("第【{}】步处理结束。。。", stepCode);
            return HandleVo.error("未知异常,请【点击】查看详情。");
        }
    }

    /**
     * 8、交易申请数据数据基础校验
     * @param channelInfo 渠道信息
     * @param handleDate 处理日期
     * @param logCode 日志编码
     * @param stepCode 处理步骤
     * @return
     */
    public HandleVo transApplyBaseCheck(ChannelInfo channelInfo, String handleDate, String logCode, Integer stepCode){
        if (channelInfo == null || StringUtils.isEmpty(handleDate) || StringUtils.isEmpty(logCode) || stepCode == null) {
            return HandleVo.error("渠道信息/处理日期/日志编码//处理步骤编码为空。");
        }

        String channelCode = channelInfo.getChannelCode();
        String versionCode = channelInfo.getVersionCode();

        if (StringUtils.isEmpty(channelCode)) {
            return HandleVo.error("渠道编码为空。");
        }

        BusinessHandleService businessHandleService = SpringUtil.getBean(BusinessHandleService.class);
        HandleDataCheck handleDataCheck = SpringUtil.getBean(HandleDataCheck.class);

        try {
            LOGGER.info("第【{}】步开始处理。。。", stepCode);
            /**
             * 1、校验appSheetSerialNo是否重复
             * 2、查询校验成功的数据
             * 3、查询接口字段
             * 4、校验
             *  4.1、校验业务编码是否支持
             *  4.2、通用基础校验
             */
            //初始化恢复状态和错误信息
            businessHandleService.initCheckStatusAndErrorMsg("trans_apply",channelCode,handleDate);

            List<String> sameAppSheetSerialNo = handleDataCheck.checkSameAppSheetSerialNo("trans_apply",channelCode,handleDate);
            if(CollectionUtils.isNotEmpty(sameAppSheetSerialNo)){
                LOGGER.error("渠道:{},日期:{},账户申请有AppSheetSerialNo重复,重复号码为:{}",channelCode,handleDate,sameAppSheetSerialNo.toString());
                //更新这些数据为失败
                businessHandleService.updateStatusAndMsgByAppSheetSerialNo("trans_apply",channelCode,handleDate,sameAppSheetSerialNo,"申请单编号重复请检查。");
            }


            //记录是否有校验错误的数据
            boolean flag = false;

            TransApplyMapper transApplyMapper = SpringUtil.getBean(TransApplyMapper.class);
            List<LinkedHashMap<String,Object>> transList = transApplyMapper.selectTransApplyForMap(channelCode,handleDate);
            if(CollectionUtils.isNotEmpty(transList)){
                List<LinkedHashMap<String,Object>> checkList = new ArrayList<>();

                //基础校验
                boolean checkFlag = handleDataCheck.baseDataCheck(transList,null,checkList,
                        ConstUtil.TRANS_SUPPORT_BUSINESS,channelCode,handleDate,
                        ConstUtil.FILE_TYPE_03,versionCode,stepCode);

                if(checkFlag){
                    flag = true;
                }

                //更新taSerialNo和错误信息
                businessHandleService.updateSerialNoAndCheckErrorList("trans_apply",transList);

                //插入错误信息
                if(CollectionUtils.isNotEmpty(checkList)){
                    exchangeAndInsertErrorDetail(logCode,checkList);
                }
            }

            LOGGER.info("第【{}】步处理结束。。。", stepCode);

            if(flag){
                return HandleVo.error("交易校验错误,请检查。");
            }
            return HandleVo.ok();

        } catch (Exception e) {
            String errorMsg = ParamsUtil.getErrorMsg(e);
            //异步插入流程日志详情表
            businessHandleService.asyncInsertLogDetail(logCode, errorMsg);
            LOGGER.error("渠道:【{}】,处理日期:【{}】,=>{DataHandle.transApplyBaseCheck}<= 发生异常 => 【{}】 ,请处理。", channelCode, handleDate, errorMsg);
            LOGGER.info("第【{}】步处理结束。。。", stepCode);
            return HandleVo.error("未知异常,请【点击】查看详情。");
        }
    }


    /**
     * 9、账户申请数据业务校验
     * @param channelInfo 渠道信息
     * @param handleDate 处理日期
     * @param logCode 日志编码
     * @param stepCode 处理步骤
     * @return
     */
    public HandleVo accountApplyBusinessCheck(ChannelInfo channelInfo, String handleDate, String logCode, Integer stepCode){
        if (channelInfo == null || StringUtils.isEmpty(handleDate) || StringUtils.isEmpty(logCode) || stepCode == null) {
            return HandleVo.error("渠道信息/处理日期/日志编码//处理步骤编码为空。");
        }

        String channelCode = channelInfo.getChannelCode();

        if (StringUtils.isEmpty(channelCode)) {
            return HandleVo.error("渠道编码为空。");
        }

        BusinessHandleService businessHandleService = SpringUtil.getBean(BusinessHandleService.class);
        HandleDataCheck handleDataCheck = SpringUtil.getBean(HandleDataCheck.class);
        //记录是否有校验错误的数据
        boolean flag = false;

        try {
            LOGGER.info("第【{}】步开始处理。。。", stepCode);
            List<LinkedHashMap<String, Object>> checkList = new ArrayList<>();

            //账户业务特殊校验
            boolean specialCheckFlag = handleDataCheck.accountSpecialBusinessCheck(channelInfo,handleDate,checkList);
            if(specialCheckFlag){
                flag = true;
            }

            /**
             * 1、重复开户,已有开户的transactionAccountId；没有直接返回校验成功
             *  1.1 如果4要素和transactionAccountId一致，直接返回，不用发送核心，
             *      判断账户状态是否是开户状态，如果不是，需要更新开户状态为开户
             *  1.2 如果4要素不一致，则该开户申请失败（失败）
             * 2、修改资料
             *  2.1 没有查到已开户数据,可能是今天的开户账户,如果都没有，失败。（失败）
             *  2.2 查看该账户状态,销户状态不允许修改资料
             *  2.3 如果4要素和transactionAccountId一致,则是修改其他信息
             *  2.4 如果4要素和transactionAccountId一致,则是修改4要素和其他信息
             * 3、销户
             *  3.1、查看销户是否有开户账户；无 （销户失败）
             *  3.2、查看该客户对应的有效合同的持仓是否为0,为0,,把所有有效合同销毁;否，销户失败（失败）
             */

            AccountApplyMapper accountApplyMapper = SpringUtil.getBean(AccountApplyMapper.class);
            List<LinkedHashMap<String,Object>> accountList = accountApplyMapper.selectAccountApplyForMap(channelCode,handleDate);
            if(CollectionUtils.isNotEmpty(accountList)) {
                for (LinkedHashMap<String,Object> account : accountList) {
                    //默认成功
                    account.put("FLOWSTEP",",stepCode_" + stepCode + ":success");
                    //账户操作业务编码
                    String businessCode = MapUtils.getString(account,"BUSINESSCODE");

                    boolean checkFlag = handleDataCheck.accountBusinessCheck(channelCode,handleDate,businessCode,
                            account,stepCode,checkList);

                    if(checkFlag) {
                        flag = true;
                    }
                }

                //更新错误信息
                businessHandleService.updateSerialNoAndCheckErrorList("account_apply",accountList);

                //插入错误信息
                if(CollectionUtils.isNotEmpty(checkList)){
                    exchangeAndInsertErrorDetail(logCode,checkList);
                }
            }

            LOGGER.info("第【{}】步处理结束。。。", stepCode);

            if(flag){
                return HandleVo.error("账户业务校验错误,请检查。");
            }
            return HandleVo.ok();

        } catch (Exception e) {
            String errorMsg = ParamsUtil.getErrorMsg(e);
            //异步插入流程日志详情表
            businessHandleService.asyncInsertLogDetail(logCode, errorMsg);
            LOGGER.error("渠道:【{}】,处理日期:【{}】,=>{DataHandle.accountApplyBusinessCheck}<= 发生异常 => 【{}】 ,请处理。", channelCode, handleDate, errorMsg);
            LOGGER.info("第【{}】步处理结束。。。", stepCode);
            return HandleVo.error("未知异常,请【点击】查看详情。");
        }
    }

    /**
     * 10、账户申请发送核心,返回taAccountId
     * @param channelInfo 渠道信息
     * @param handleDate 处理日期
     * @param logCode 日志编码
     * @param stepCode 处理步骤
     * @return
     */
    public HandleVo sendAccountApplyToCore(ChannelInfo channelInfo, String handleDate, String logCode, Integer stepCode) {
        if (channelInfo == null || StringUtils.isEmpty(handleDate) || StringUtils.isEmpty(logCode) || stepCode == null) {
            return HandleVo.error("渠道信息/处理日期/日志编码//处理步骤编码为空。");
        }

        String channelCode = channelInfo.getChannelCode();

        if (StringUtils.isEmpty(channelCode)) {
            return HandleVo.error("渠道编码为空。");
        }

        BusinessHandleService businessHandleService = SpringUtil.getBean(BusinessHandleService.class);
        //记录是否有校验错误的数据
        boolean flag = false;

        try {
            LOGGER.info("第【{}】步开始处理。。。", stepCode);
            List<LinkedHashMap<String, Object>> checkList = new ArrayList<>();

            AccountApplyMapper accountApplyMapper = SpringUtil.getBean(AccountApplyMapper.class);
            TaService taService  = SpringUtil.getBean(TaService.class);
            List<LinkedHashMap<String,Object>> sendToTaAccountList = accountApplyMapper.selectAccountApplySendTaForMap(channelCode,handleDate);

            if(CollectionUtils.isNotEmpty(sendToTaAccountList)) {
                for (LinkedHashMap<String, Object> sendToTaAccount : sendToTaAccountList) {
                    //默认成功
                    sendToTaAccount.put("FLOWSTEP", ",stepCode_" + stepCode + ":success");

                    // TODO  简单处理，逻辑不完善
                    ResultVo resultVo = taService.openAccount(sendToTaAccount);
                    if (200 == resultVo.getCode()) {
                        String taAccountId = String.valueOf(resultVo.getData());
                        sendToTaAccount.put("TAACCOUNTID", taAccountId);
                        sendToTaAccount.put("SENDTAFLAG", 1);
                        //插入账户状态表
                        businessHandleService.insertAccountStatus(sendToTaAccount,taAccountId);
                    } else {
                        String errorMsg = resultVo.getMsg();
                        sendToTaAccount.put("FLOWSTEP", ",stepCode_" + stepCode + ":failed");
                        sendToTaAccount.put("CHECKSTATUS", 0);
                        sendToTaAccount.put("SENDTAFLAG", 2);
                        sendToTaAccount.put("ERRORMSG", errorMsg);
                        checkList.add(sendToTaAccount);
                        flag = true;
                        LOGGER.info("{}渠道,{}日期,调用开户接口返回失败。",channelCode,handleDate);
                    }
                }

                //更新错误信息
                businessHandleService.updateSerialNoAndCheckErrorList("account_apply",sendToTaAccountList);

                //插入错误信息
                if(CollectionUtils.isNotEmpty(checkList)){
                    exchangeAndInsertErrorDetail(logCode,checkList);
                }
            }

            LOGGER.info("第【{}】步处理结束。。。", stepCode);

            if (flag) {
                return HandleVo.error("账户发送TA错误错误,请检查。");
            }
            return HandleVo.ok();

        } catch (Exception e) {
            String errorMsg = ParamsUtil.getErrorMsg(e);
            //异步插入流程日志详情表
            businessHandleService.asyncInsertLogDetail(logCode, errorMsg);
            LOGGER.error("渠道:【{}】,处理日期:【{}】,=>{DataHandle.sendAccountApplyToCore}<= 发生异常 => 【{}】 ,请处理。", channelCode, handleDate, errorMsg);
            LOGGER.info("第【{}】步处理结束。。。", stepCode);
            return HandleVo.error("未知异常,请【点击】查看详情。");
        }
    }

    /**
     * 11、电子合同申请数据业务校验
     * @param channelInfo 渠道信息
     * @param handleDate 处理日期
     * @param logCode 日志编码
     * @param stepCode 处理步骤
     * @return
     */
    public HandleVo elContractBusinessCheck(ChannelInfo channelInfo, String handleDate, String logCode, Integer stepCode){
        if (channelInfo == null || StringUtils.isEmpty(handleDate) || StringUtils.isEmpty(logCode) || stepCode == null) {
            return HandleVo.error("渠道信息/处理日期/日志编码//处理步骤编码为空。");
        }

        String channelCode = channelInfo.getChannelCode();

        if (StringUtils.isEmpty(channelCode)) {
            return HandleVo.error("渠道编码为空。");
        }

        BusinessHandleService businessHandleService = SpringUtil.getBean(BusinessHandleService.class);
        //记录是否有校验错误的数据
        boolean flag = false;

        try {
            LOGGER.info("第【{}】步开始处理。。。", stepCode);
            List<LinkedHashMap<String, Object>> checkList = new ArrayList<>();


            LOGGER.info("第【{}】步处理结束。。。", stepCode);

            if (flag) {
                return HandleVo.error("电子合同业务校验错误,请检查。");
            }

            return HandleVo.ok();

        } catch (Exception e) {
            String errorMsg = ParamsUtil.getErrorMsg(e);
            //异步插入流程日志详情表
            businessHandleService.asyncInsertLogDetail(logCode, errorMsg);
            LOGGER.error("渠道:【{}】,处理日期:【{}】,=>{DataHandle.elContractBusinessCheck}<= 发生异常 => 【{}】 ,请处理。", channelCode, handleDate, errorMsg);
            LOGGER.info("第【{}】步处理结束。。。", stepCode);
            return HandleVo.error("未知异常,请【点击】查看详情。");
        }
    }


    /**
     * 12、交易申请数据业务校验
     * @param channelInfo 渠道信息
     * @param handleDate 处理日期
     * @param logCode 日志编码
     * @param stepCode 处理步骤
     * @return
     */
    public HandleVo transApplyBusinessCheck(ChannelInfo channelInfo, String handleDate, String logCode, Integer stepCode){
        if (channelInfo == null || StringUtils.isEmpty(handleDate) || StringUtils.isEmpty(logCode) || stepCode == null) {
            return HandleVo.error("渠道信息/处理日期/日志编码//处理步骤编码为空。");
        }

        String channelCode = channelInfo.getChannelCode();

        if (StringUtils.isEmpty(channelCode)) {
            return HandleVo.error("渠道编码为空。");
        }

        BusinessHandleService businessHandleService = SpringUtil.getBean(BusinessHandleService.class);
        HandleDataCheck handleDataCheck = SpringUtil.getBean(HandleDataCheck.class);

        //记录是否有校验错误的数据
        boolean flag = false;

        try {
            LOGGER.info("第【{}】步开始处理。。。", stepCode);
            List<LinkedHashMap<String, Object>> checkList = new ArrayList<>();
            /**
             * 0、随机分配TA代码
             *
             * 1、校验产品是否是在售产品
             * 2、校验产品没有TA代码
             * 3、校验当前交易的账户是否已开户并是开户状态
             *
             * 4、校验当前产品的行情状态和当前交易业务是否相符
             * 5、校验认购交易、申购交易
             * 6、校验赎回交易
             * 7、校验收益级别收益率
             *
             * 8、重新分配TA代码
             */


            //0、随机分配TA代码,并更新taAccountId
            businessHandleService.randomAllocationTaFundCode(channelCode,handleDate);

            //1-3
            boolean topCheckFlag = handleDataCheck.transApplyBusinessTopCheck(channelCode,handleDate,stepCode,checkList);
            if(topCheckFlag){
                flag = true;
            }

            TransApplyMapper transApplyMapper = SpringUtil.getBean(TransApplyMapper.class);
            List<LinkedHashMap<String,Object>> transList = transApplyMapper.selectTransApplyForMap(channelCode,handleDate);
            if(CollectionUtils.isNotEmpty(transList)){
                //查询产品-行情数据
                Map<String,String> fundMarketMap = businessHandleService.selectFundMarketStatusMap(channelCode,handleDate);

                for (LinkedHashMap<String,Object> trans : transList) {
                    //默认成功
                    trans.put("FLOWSTEP", ",stepCode_" + stepCode + ":success");
                    //4-7
                    boolean coreCheckFlag = handleDataCheck.transApplyBusinessCoreCheck(trans,fundMarketMap,checkList);
                    if(coreCheckFlag){
                        trans.put("FLOWSTEP", ",stepCode_" + stepCode + ":failed");
                        flag = true;
                    }
                }

                //更新错误信息
                businessHandleService.updateSerialNoAndCheckErrorList("trans_apply",transList);
            }

            //8、重新分配TA代码,某些产品类型有合同号限制  TODO
            handleDataCheck.reloadAllocationTaFundCode(channelCode,handleDate,stepCode,checkList);

            //插入错误信息
            if(CollectionUtils.isNotEmpty(checkList)){
                exchangeAndInsertErrorDetail(logCode,checkList);
            }

            if(flag){
                return HandleVo.error("交易业务校验错误,请检查。");
            }

            LOGGER.info("第【{}】步处理结束。。。", stepCode);
            return HandleVo.ok();

        } catch (Exception e) {
            String errorMsg = ParamsUtil.getErrorMsg(e);
            //异步插入流程日志详情表
            businessHandleService.asyncInsertLogDetail(logCode, errorMsg);
            LOGGER.error("渠道:【{}】,处理日期:【{}】,=>{DataHandle.transApplyBusinessCheck}<= 发生异常 => 【{}】 ,请处理。", channelCode, handleDate, errorMsg);
            LOGGER.info("第【{}】步处理结束。。。", stepCode);
            return HandleVo.error("未知异常,请【点击】查看详情。");
        }
    }



    /**
     * 13、交易申请数据发送核心   TODO
     * @param channelInfo 渠道信息
     * @param handleDate 处理日期
     * @param logCode 日志编码
     * @param stepCode 处理步骤
     * @return
     */
    public HandleVo sendTransApplyToCore(ChannelInfo channelInfo, String handleDate, String logCode, Integer stepCode){
        if (channelInfo == null || StringUtils.isEmpty(handleDate) || StringUtils.isEmpty(logCode) || stepCode == null) {
            return HandleVo.error("渠道信息/处理日期/日志编码//处理步骤编码为空。");
        }

        String channelCode = channelInfo.getChannelCode();

        if (StringUtils.isEmpty(channelCode)) {
            return HandleVo.error("渠道编码为空。");
        }

        BusinessHandleService businessHandleService = SpringUtil.getBean(BusinessHandleService.class);

        //记录是否有校验错误的数据
        boolean flag = false;

        try {
            LOGGER.info("第【{}】步开始处理。。。", stepCode);
            List<LinkedHashMap<String, Object>> checkList = new ArrayList<>();
            TransApplyMapper transApplyMapper = SpringUtil.getBean(TransApplyMapper.class);
            List<LinkedHashMap<String,Object>> transList = transApplyMapper.selectTransApplySendTaForMap(channelCode,handleDate);

            for (LinkedHashMap<String,Object> trans : transList) {
                String businessCode = MapUtils.getString(trans,"BUSINESSCODE");
                ResultVo resultVo = null;
                if(ConstUtil.RG_TRANS.equals(businessCode) || ConstUtil.SG_TRANS.equals(businessCode)){
                    resultVo = businessHandleService.sendTransBuyApplyToTa(trans);
                }else if(ConstUtil.SH_TRANS.equals(businessCode)){
                    resultVo = businessHandleService.sendTransRedeemApplyToTa(trans);
                }

                if (200 == resultVo.getCode()) {
                    Map<String,Object> retMap = (Map<String, Object>) resultVo.getData();
                    trans.put("FLOWSTEP", ",stepCode_" + stepCode + ":success");
                    //更新交易
                    transApplyMapper.updateContractAndRequestNo(trans,retMap);

                    TransContractMapper transContractMapper = SpringUtil.getBean(TransContractMapper.class);
                    String fundCode = MapUtils.getString(trans,"FUNDCODE");
                    String transactionAccountId = MapUtils.getString(trans,"TRANSACTIONACCOUNTID");
                    TransContract transContract = transContractMapper.selectOne(new TransContract(channelCode,fundCode,transactionAccountId,"01"));
                    if(transContract == null){
                        //插入
                        transContractMapper.insertTransContract(trans,retMap);
                    }else{
                        //更新合同金额和appSheetSerialNo
                        String appSheetSerialNo = MapUtils.getString(trans,"APPSHEETSERIALNO");
                        BigDecimal applicationAmount = new BigDecimal(MapUtils.getString(trans,"APPLICATIONAMOUNT","0"));
                        transContractMapper.updateContractAmount(channelCode,fundCode,transactionAccountId,appSheetSerialNo,applicationAmount);
                    }
                }else{
                    String msg = resultVo.getMsg();
                    trans.put("ERRORMSG",msg);
                    trans.put("FLOWSTEP", ",stepCode_" + stepCode + ":failed");
                    checkList.add(trans);
                    flag = true;
                    transApplyMapper.updateTransSendTaStatusAndMsg(trans,msg);
                }
            }

            //插入错误信息
            if(CollectionUtils.isNotEmpty(checkList)){
                exchangeAndInsertErrorDetail(logCode,checkList);
            }

            if(flag){
                return HandleVo.error("交易发送核心错误,请检查。");
            }

            LOGGER.info("第【{}】步处理结束。。。", stepCode);
            return HandleVo.ok();

        } catch (Exception e) {
            String errorMsg = ParamsUtil.getErrorMsg(e);
            //异步插入流程日志详情表
            businessHandleService.asyncInsertLogDetail(logCode, errorMsg);
            LOGGER.error("渠道:【{}】,处理日期:【{}】,=>{DataHandle.sendTransApplyToCore}<= 发生异常 => 【{}】 ,请处理。", channelCode, handleDate, errorMsg);
            LOGGER.info("第【{}】步处理结束。。。", stepCode);
            return HandleVo.error("未知异常,请【点击】查看详情。");
        }
    }

    /**
     * 14、发送交易预确认文件  TODO
     * @param channelInfo 渠道信息
     * @param handleDate 处理日期
     * @param logCode 日志编码
     * @param stepCode 处理步骤
     * @return
     */
    public HandleVo sendBeforeCfmFile(ChannelInfo channelInfo, String handleDate, String logCode, Integer stepCode){
        if (channelInfo == null || StringUtils.isEmpty(handleDate) || StringUtils.isEmpty(logCode) || stepCode == null) {
            return HandleVo.error("渠道信息/处理日期/日志编码//处理步骤编码为空。");
        }

        String channelCode = channelInfo.getChannelCode();

        if (StringUtils.isEmpty(channelCode)) {
            return HandleVo.error("渠道编码为空。");
        }

        BusinessHandleService businessHandleService = SpringUtil.getBean(BusinessHandleService.class);
        HandleDataCheck handleDataCheck = SpringUtil.getBean(HandleDataCheck.class);

        //记录是否有校验错误的数据
        boolean flag = false;

        try {
            LOGGER.info("第【{}】步开始处理。。。", stepCode);
            List<LinkedHashMap<String, Object>> checkList = new ArrayList<>();

            //插入错误信息
            if(CollectionUtils.isNotEmpty(checkList)){
                exchangeAndInsertErrorDetail(logCode,checkList);
            }

            if(flag){
                return HandleVo.error("交易业务校验错误,请检查。");
            }

            LOGGER.info("第【{}】步处理结束。。。", stepCode);
            return HandleVo.ok();

        } catch (Exception e) {
            String errorMsg = ParamsUtil.getErrorMsg(e);
            //异步插入流程日志详情表
            businessHandleService.asyncInsertLogDetail(logCode, errorMsg);
            LOGGER.error("渠道:【{}】,处理日期:【{}】,=>{DataHandle.sendBeforeCfmFile}<= 发生异常 => 【{}】 ,请处理。", channelCode, handleDate, errorMsg);
            LOGGER.info("第【{}】步处理结束。。。", stepCode);
            return HandleVo.error("未知异常,请【点击】查看详情。");
        }
    }


    /**
     * 获得所有需要下载的文件名称
     * @param channelInfo 渠道信息
     * @param handleDate 处理日期
     * @return
     */
    private Set<String> getAllNeedDownLoadFileNames(ChannelInfo channelInfo, String handleDate) {
        Set<String> fileNames = new HashSet<>();

        String creatorCode = channelInfo.getSendCode();
        String receiverCode = channelInfo.getReceiveCode();
        String dealFile = channelInfo.getDealFileType();

        List<String> dealFiles = Arrays.asList(dealFile.split(","));
        dealFiles.forEach(v->{
            String indexFileName = FileUtil.buildIndexFileName(creatorCode,receiverCode,handleDate,FileUtil.buildIndexFileNamePrefix(v));
            String fileName = FileUtil.buildFileName(creatorCode,receiverCode,handleDate,v);
            fileNames.add(indexFileName);
            fileNames.add(fileName);
        });

        return fileNames;
    }

    /**
     * 需要的正式文件名称
     * @param channelInfo 渠道信息
     * @param handleDate 处理日期
     * @return
     */
    private Set<String> getAllNeedFileNames(ChannelInfo channelInfo, String handleDate) {
        Set<String> fileNames = new HashSet<>();

        String creatorCode = channelInfo.getSendCode();
        String receiverCode = channelInfo.getReceiveCode();
        String dealFile = channelInfo.getDealFileType();

        List<String> dealFiles = Arrays.asList(dealFile.split(","));
        dealFiles.forEach(v->{
            String fileName = FileUtil.buildFileName(creatorCode,receiverCode,handleDate,v);
            fileNames.add(fileName);
        });

        return fileNames;
    }

    /**
     * 基础校验插入日志详情
     * @param logCode 日志编码
     * @param checkList 校验错误集合
     */
    private void exchangeAndInsertErrorDetail(String logCode, List<LinkedHashMap<String, Object>> checkList) {

        List<LinkedHashMap<String, Object>> errorMsgList = new ArrayList<>();
        checkList.forEach(v->{
            LinkedHashMap<String, Object> errorMsg = new LinkedHashMap<>();
            errorMsg.put("渠道编码",v.get("CHANNELCODE"));
            errorMsg.put("处理日期",v.get("HANDLEDATE"));
            if(StringUtils.isNotEmpty(MapUtils.getString(v,"APPSHEETSERIALNO")))errorMsg.put("申请单编号",v.get("APPSHEETSERIALNO"));
            if(StringUtils.isNotEmpty(MapUtils.getString(v,"TRANSACTIONACCOUNTID")))errorMsg.put("投资人基金交易账号",v.get("TRANSACTIONACCOUNTID"));
            if(StringUtils.isNotEmpty(MapUtils.getString(v,"INVESTORNAME")))errorMsg.put("投资人姓名",v.get("INVESTORNAME"));
            if(StringUtils.isNotEmpty(MapUtils.getString(v,"FUNDCODE")))errorMsg.put("产品",v.get("FUNDCODE"));
            if(StringUtils.isNotEmpty(MapUtils.getString(v,"SERIALNO")))errorMsg.put("流水号",v.get("SERIALNO"));
            if(StringUtils.isNotEmpty(MapUtils.getString(v,"BUSINESSCODE")))errorMsg.put("业务代码",v.get("BUSINESSCODE"));
            errorMsg.put("错误信息",v.get("ERRORMSG"));
            errorMsgList.add(errorMsg);
        });
        //异步插入流程日志详情表
        BusinessHandleService businessHandleService = SpringUtil.getBean(BusinessHandleService.class);
        businessHandleService.asyncInsertLogDetail(logCode, JsonUtil.getListMapToLineFeedJson(errorMsgList));
    }

}
